package calcs;

import static util.UserInputChecker.checkInput;
import static util.UserInputChecker.setCalculated;
import static util.UserInputChecker.setInitial;
import static util.Util.*;
import gui.ErrorMessage;
import gui.MyFrame;
import gui.data.D2.QuadrangleOutputGui;

public class QuadrangleCalculator extends Thread {
	int guide;
	double adLength, dcLength, cbLength, baLength, dabAngle, abcAngle,
			bcdAngle, cdaAngle, diagonal1, diagonal2, circumference, area,
			height, help1 = 0, help2 = 0;
	boolean found = false, before = false, calculated = false;
	MyFrame myFrame = null;

	public QuadrangleCalculator(int guide, double adLength, double dcLength,
			double cbLength, double baLength, double dabAngle, double abcAngle,
			double bcdAngle, double cdaAngle, double diagonal1,
			double diagonal2, double circumference, double area, double height,
			final MyFrame myFrame) {
		this.myFrame = myFrame;
		this.guide = guide;
		this.adLength = adLength;
		this.dcLength = dcLength;
		this.cbLength = cbLength;
		this.baLength = baLength;
		this.dabAngle = dabAngle;
		this.abcAngle = abcAngle;
		this.bcdAngle = bcdAngle;
		this.cdaAngle = cdaAngle;
		this.diagonal1 = diagonal1;
		this.diagonal2 = diagonal2;
		this.circumference = circumference;
		this.area = area;
		this.height = height;
		setInitial(adLength, dcLength, cbLength, baLength, dabAngle, abcAngle,
				bcdAngle, cdaAngle, diagonal1, diagonal2, circumference, area,
				height);
		start();
	}

	public QuadrangleCalculator(int guide, double adLength, double dcLength,
			double cbLength, double baLength, double dabAngle, double abcAngle,
			double bcdAngle, double cdaAngle, double diagonal1,
			double diagonal2, double circumference, double area, double height) {
		this.guide = guide;
		this.adLength = adLength;
		this.dcLength = dcLength;
		this.cbLength = cbLength;
		this.baLength = baLength;
		this.dabAngle = dabAngle;
		this.abcAngle = abcAngle;
		this.bcdAngle = bcdAngle;
		this.cdaAngle = cdaAngle;
		this.diagonal1 = diagonal1;
		this.diagonal2 = diagonal2;
		this.circumference = circumference;
		this.area = area;
		this.height = height;
	}

	public void run() {
		switch (guide) {
		case 1:
			calculateSquare();
			setSquareDefaults();
			break;
		case 2:
			calculateOblong();
			setOblongDefaults();
			break;
		case 3:
			calculateRhombus();
			setRhombusDefaults();
			break;
		case 4:
			calculateRhomboid();
			setRhomboidDefaults();
			break;
		case 5:
			calculateTrapezium();
			break;
		case 6:
			calculateKite();
			setKiteDefaults();
			break;
		}
		finish();
	}

	private void finish() {
		adLength = roundToDecimals(adLength, 2);
		dcLength = roundToDecimals(dcLength, 2);
		cbLength = roundToDecimals(cbLength, 2);
		baLength = roundToDecimals(baLength, 2);
		dabAngle = roundToDecimals(dabAngle, 2);
		abcAngle = roundToDecimals(abcAngle, 2);
		bcdAngle = roundToDecimals(bcdAngle, 2);
		cdaAngle = roundToDecimals(cdaAngle, 2);
		diagonal1 = roundToDecimals(diagonal1, 2);
		diagonal2 = roundToDecimals(diagonal2, 2);
		circumference = roundToDecimals(circumference, 2);
		area = roundToDecimals(area, 2);
		height = roundToDecimals(height, 2);
		if (myFrame != null) {
			setCalculated(adLength, dcLength, cbLength, baLength, dabAngle,
					abcAngle, bcdAngle, cdaAngle, diagonal1, diagonal2,
					circumference, area, height);
			if (checkInput()) {
				myFrame.setDataPanel(new QuadrangleOutputGui(guide, adLength,
						dcLength, cbLength, baLength, dabAngle, abcAngle,
						bcdAngle, cdaAngle, diagonal1, diagonal2,
						circumference, area, height), "QUADRANGLE_OUTPUT");
			} else {
				new ErrorMessage("Check input");
			}
		}
	}

	private void calculateKite() {
		do {
			found = false;
			before = false;
			calculated = false;

			/*
			 * before = adLength != 0; calculateKiteSide1(); if (!before &&
			 * found) { calculated = true; }
			 * 
			 * before = dcLength != 0; calculateKiteSide2(); if (!before &&
			 * found) { calculated = true; }
			 * 
			 * before = abcAngle != 0; calculateKiteAbcAngle(); if (!before &&
			 * found) { calculated = true; }
			 * 
			 * before = bcdAngle != 0; calculateKiteBcdAngle(); if (!before &&
			 * found) { calculated = true; }
			 * 
			 * before = dabAngle != 0; calculateKiteDabAngle(); if (!before &&
			 * found) { calculated = true; }
			 * 
			 * before = area != 0; calculateKiteArea(); if (!before && found) {
			 * calculated = true; }
			 * 
			 * before = circumference != 0; calculateKiteCircumference(); if
			 * (!before && found) { calculated = true; }
			 * 
			 * before = diagonal1 != 0; calculateKiteDiagonal1(); if (!before &&
			 * found) { calculated = true; }
			 * 
			 * before = diagonal2 != 0; calculateKiteDiagonal2(); if (!before &&
			 * found) { calculated = true; }
			 */

			if (adLength == 0) {
				calculateKiteSide1();
			}
			if (dcLength == 0) {
				calculateKiteSide2();
			}
			if (abcAngle == 0) {
				calculateKiteAbcAngle();
			}
			if (bcdAngle == 0) {
				calculateKiteBcdAngle();
			}
			if (dabAngle == 0) {
				calculateKiteDabAngle();
			}
			if (area == 0) {
				calculateKiteArea();
			}
			if (circumference == 0) {
				calculateKiteCircumference();
			}
			if (diagonal1 == 0) {
				calculateKiteDiagonal1();
			}
			if (diagonal2 == 0) {
				calculateKiteDiagonal2();
			}
		} while (calculated);
	}

	private void calculateKiteSide1() {
		if (diagonal2 != 0 && dabAngle != 0) {
			adLength = diagonal2 / (2 * Math.sin(Math.toRadians(dabAngle / 2)));
			found = true;
		} else if (area != 0 && abcAngle != 0 && dcLength != 0) {
			adLength = area / (dcLength * Math.sin(Math.toRadians(abcAngle)));
			found = true;
		} else if (circumference != 0 && dcLength != 0) {
			adLength = (circumference - (2 * dcLength) / 2);
			found = true;
		}
	}

	private void calculateKiteSide2() {
		if (diagonal2 != 0) {
			if (bcdAngle != 0) {
				dcLength = diagonal2
						/ (2 * Math.sin(Math.toRadians(bcdAngle / 2)));
				found = true;
			}
		} else if (area != 0 && abcAngle != 0 && adLength != 0) {
			dcLength = area / (adLength * Math.sin(Math.toRadians(abcAngle)));
			found = true;
		} else if (circumference != 0 && adLength != 0) {
			dcLength = (circumference - (2 * adLength) / 2);
			found = true;
		}
	}

	private void calculateKiteAbcAngle() {
		if (dabAngle != 0 && abcAngle != 0) {
			abcAngle = (360 - dabAngle - abcAngle) / 2;
			found = true;
		} else if (diagonal2 != 0 && adLength != 0 && dcLength != 0) {
			abcAngle = Math.toDegrees(Math.acos((diagonal2 / (2 * dcLength)))
					+ Math.acos((diagonal2 / (2 * adLength))));
			found = true;
		}
	}

	private void calculateKiteDabAngle() {
		if (abcAngle != 0 && bcdAngle != 0) {
			dabAngle = 360 - (2 * abcAngle) - bcdAngle;
			found = true;
		} else if (diagonal2 != 0 && adLength != 0) {
			dabAngle = 2 * Math
					.toDegrees(Math.asin(diagonal2 / (2 * adLength)));
			found = true;
		}
	}

	private void calculateKiteBcdAngle() {
		if (abcAngle != 0 && dabAngle != 0) {
			bcdAngle = 360 - (2 * abcAngle) - dabAngle;
			found = true;
		} else if (diagonal2 != 0 && dcLength != 0) {
			bcdAngle = Math
					.toDegrees(2 * Math.asin(diagonal2 / (2 * dcLength)));
			found = true;
		}
	}

	private void calculateKiteArea() {
		if (diagonal1 != 0 && diagonal2 != 0) {
			area = (diagonal1 * diagonal2) / 2;
			found = true;
		} else if (adLength != 0 && dcLength != 0 && abcAngle != 0) {
			area = dcLength * adLength * Math.sin(Math.toRadians(abcAngle));
			found = true;
		}
	}

	private void calculateKiteCircumference() {
		if (adLength != 0 && dcLength != 0) {
			circumference = (2 * adLength) + (2 * dcLength);
			found = true;
		}
	}

	private void calculateKiteDiagonal1() {
		if (adLength != 0 && dcLength != 0 && diagonal2 != 0) {
			diagonal1 = Math.sqrt(Math.pow(adLength, 2)
					- Math.pow(diagonal2 / 2, 2))
					+ Math.sqrt(Math.pow(dcLength, 2)
							- Math.pow(diagonal2 / 2, 2));
			found = true;
		} else if (adLength != 0 && dcLength != 0 && abcAngle != 0) {
			diagonal1 = Math.sqrt(Math.pow(adLength, 2)
					+ Math.pow(dcLength, 2)
					- (2 * adLength * dcLength * Math.cos(Math
							.toRadians(abcAngle))));
			found = true;
		} else if (area != 0) {
			diagonal1 = (2 * area) / diagonal2;
			found = true;
		}
	}

	private void calculateKiteDiagonal2() {
		if (adLength != 0 && dabAngle != 0) {
			diagonal2 = Math.sqrt((2 * Math.pow(adLength, 2))
					- (2 * Math.pow(adLength, 2) * Math.cos(Math
							.toRadians(dabAngle))));
			found = true;
		} else if (dcLength != 0 && bcdAngle != 0) {
			diagonal2 = Math.sqrt((2 * Math.pow(dcLength, 2))
					- (2 * Math.pow(dcLength, 2) * Math.cos(Math
							.toRadians(bcdAngle))));
			found = true;
		} else if (area != 0) {
			diagonal2 = (2 * area) / diagonal1;
			found = true;
		}
	}

	private void setKiteDefaults() {
		cdaAngle = abcAngle;
		baLength = adLength;
		cbLength = dcLength;
	}

	private void calculateTrapezium() {
		do {
			found = false;
			before = false;
			calculated = false;

			before = baLength != 0;
			calculateTrapeziumBottom();
			if (!before && found) {
				calculated = true;
			}

			before = dcLength != 0;
			calculateTrapeziumTop();
			if (!before && found) {
				calculated = true;
			}

			before = adLength != 0;
			calculateTrapeziumLeft();
			if (!before && found) {
				calculated = true;
			}

			before = cbLength != 0;
			calculateTrapeziumRight();
			if (!before && found) {
				calculated = true;
			}

			before = abcAngle != 0;
			calculateTrapeziumAbcAngle();
			if (!before && found) {
				calculated = true;
			}

			before = dabAngle != 0;
			calculateTrapeziumDabAngle();
			if (!before && found) {
				calculated = true;
			}

			before = bcdAngle != 0;
			calculateTrapeziumBcdAngle();
			if (!before && found) {
				calculated = true;
			}

			before = cdaAngle != 0;
			calculateTrapeziumCdaAngle();
			if (!before && found) {
				calculated = true;
			}

			before = area != 0;
			calculateTrapeziumArea();
			if (!before && found) {
				calculated = true;
			}

			before = circumference != 0;
			calculateTrapeziumCircumference();
			if (!before && found) {
				calculated = true;
			}

			before = diagonal1 != 0;
			calculateTrapeziumDiagonal1();
			if (!before && found) {
				calculated = true;
			}

			before = diagonal2 != 0;
			calculateTrapeziumDiagonal2();
			if (!before && found) {
				calculated = true;
			}

			before = height != 0;
			calculateTrapeziumHeight();
			if (!before && found) {
				calculated = true;
			}

			before = help1 != 0;
			calculateTrapeziumHelp1();
			if (!before && found) {
				calculated = true;
			}

			before = help2 != 0;
			calculateTrapeziumHelp2();
			if (!before && found) {
				calculated = true;
			}

		} while (calculated);
	}

	private void calculateTrapeziumHelp1() {
		if (baLength != 0 && dcLength != 0 && help2 != 0) {
			help1 = baLength - dcLength - help2;
			found = true;
		} else if (adLength != 0 && height != 0) {
			help1 = Math.sqrt(Math.pow(adLength, 2) - Math.pow(height, 2));
			found = true;
		}
	}

	private void calculateTrapeziumHelp2() {
		if (baLength != 0 && dcLength != 0 && help1 != 0) {
			help2 = baLength - dcLength - help1;
			found = true;
		} else if (cbLength != 0 && height != 0) {
			help2 = Math.sqrt(Math.pow(cbLength, 2) - Math.pow(height, 2));
			found = true;
		}
	}

	private void calculateTrapeziumBottom() {
		if (dcLength != 0 && circumference != 0 && cbLength != 0
				&& adLength != 0) {
			baLength = circumference - dcLength - cbLength - adLength;
			found = true;
		} else if (dcLength != 0 && help1 != 0 && help2 != 0) {
			baLength = help1 + help2 + dcLength;
			found = true;
		} else if (dcLength != 0 && area != 0 && height != 0) {
			baLength = ((2 * area) / height) - dcLength;
			found = true;
		} else if (height != 0) {
			if (diagonal1 != 0 && help2 != 0) {
				baLength = Math.sqrt(Math.pow(diagonal1, 2)
						- Math.pow(height, 2))
						+ help2;
				found = true;
			} else if (diagonal2 != 0 && help1 != 0) {
				baLength = Math.sqrt(Math.pow(diagonal2, 2)
						- Math.pow(height, 2))
						+ help1;
				found = true;
			}
		}
	}

	private void calculateTrapeziumTop() {
		if (baLength != 0) {
			if (circumference != 0 && cbLength != 0 && adLength != 0) {
				dcLength = circumference - baLength - cbLength - adLength;
				found = true;
			} else if (help1 != 0 && help2 != 0) {
				dcLength = baLength - help1 - help2;
				found = true;
			} else if (area != 0 && height != 0) {
				dcLength = ((2 * area) / height) - baLength;
				found = true;
			}
		}
	}

	private void calculateTrapeziumLeft() {
		if (circumference != 0 && baLength != 0 && dcLength != 0
				&& cbLength != 0) {
			adLength = circumference - baLength - dcLength - cbLength;
			found = true;
		} else if (dabAngle != 0 && help1 != 0) {
			adLength = help1 / Math.cos(Math.toRadians(dabAngle));
			found = true;
		} else if (height != 0) {
			if (dabAngle != 0) {
				adLength = height / Math.sin(Math.toRadians(dabAngle));
				found = true;
			} else if (help1 != 0) {
				adLength = Math.sqrt(Math.pow(help1, 2) + Math.pow(height, 2));
				found = true;
			}
		}
	}

	private void calculateTrapeziumRight() {
		if (circumference != 0 && baLength != 0 && dcLength != 0
				&& adLength != 0) {
			cbLength = circumference - baLength - dcLength - adLength;
			found = true;
		} else if (abcAngle != 0 && help2 != 0) {
			cbLength = help1 / Math.cos(Math.toRadians(abcAngle));
			found = true;
		} else if (height != 0) {
			if (abcAngle != 0) {
				cbLength = height / Math.sin(Math.toRadians(abcAngle));
				found = true;
			} else if (help2 != 0) {
				cbLength = Math.sqrt(Math.pow(help1, 2) + Math.pow(height, 2));
				found = true;
			}
		}
	}

	private void calculateTrapeziumAbcAngle() {
		if (bcdAngle != 0) {
			abcAngle = 180 - bcdAngle;
			found = true;
		} else if (cbLength != 0) {
			if (height != 0) {
				abcAngle = Math.toDegrees(Math.asin(height / cbLength));
				found = true;
			} else if (help2 != 0) {
				abcAngle = Math.toDegrees(Math.acos(help2 / cbLength));
				found = true;
			} else if (baLength != 0 && diagonal1 != 0) {
				abcAngle = Math.toDegrees(Math.acos((Math.pow(baLength, 2)
						+ Math.pow(cbLength, 2) - Math.pow(diagonal1, 2))
						/ (2 * baLength * cbLength)));
				found = true;
			}
		}
	}

	private void calculateTrapeziumDabAngle() {
		if (cdaAngle != 0) {
			dabAngle = 180 - cdaAngle;
			found = true;
		} else if (adLength != 0) {
			if (height != 0) {
				dabAngle = Math.toDegrees(Math.asin(height / adLength));
				found = true;
			} else if (help1 != 0) {
				dabAngle = Math.toDegrees(Math.acos(help1 / adLength));
				found = true;
			} else if (baLength != 0 && diagonal2 != 0) {
				dabAngle = Math.toDegrees(Math.acos((Math.pow(baLength, 2)
						+ Math.pow(adLength, 2) - Math.pow(diagonal2, 2))
						/ (2 * baLength * adLength)));
				found = true;
			}
		}
	}

	private void calculateTrapeziumBcdAngle() {
		if (abcAngle != 0) {
			bcdAngle = 180 - abcAngle;
			found = true;
		} else if (cbLength != 0 && dcLength != 0 && diagonal2 != 0) {
			bcdAngle = Math.toDegrees(Math.acos((Math.pow(dcLength, 2)
					+ Math.pow(cbLength, 2) - Math.pow(diagonal2, 2))
					/ (2 * dcLength * cbLength)));
			found = true;
		}
	}

	private void calculateTrapeziumCdaAngle() {
		if (dabAngle != 0) {
			cdaAngle = 180 - dabAngle;
			found = true;
		} else if (dcLength != 0 && adLength != 0 && diagonal1 != 0) {
			cdaAngle = Math.toDegrees(Math.acos((Math.pow(adLength, 2)
					+ Math.pow(dcLength, 2) - Math.pow(diagonal1, 2))
					/ (2 * adLength * dcLength)));
			found = true;
		}
	}

	private void calculateTrapeziumArea() {
		if (baLength != 0 && dcLength != 0 && height != 0) {
			area = ((baLength + dcLength) / 2) * height;
			found = true;
		}
	}

	private void calculateTrapeziumCircumference() {
		if (baLength != 0 && dcLength != 0 && cbLength != 0 && adLength != 0) {
			circumference = baLength + dcLength + cbLength + adLength;
			found = true;
		}
	}

	private void calculateTrapeziumDiagonal1() {
		if (baLength != 0 && height != 0 && help2 != 0) {
			diagonal1 = Math.sqrt(Math.pow(baLength - help2, 2)
					+ Math.pow(height, 2));
			found = true;
		} else if (baLength != 0 && cbLength != 0 && abcAngle != 0) {
			diagonal1 = Math.sqrt(Math.pow(baLength, 2)
					+ Math.pow(cbLength, 2)
					- (2 * baLength * cbLength * Math.cos(Math
							.toRadians(abcAngle))));
			found = true;
		} else if (adLength != 0 && dcLength != 0 && cdaAngle != 0) {
			diagonal1 = Math.sqrt(Math.pow(adLength, 2)
					+ Math.pow(dcLength, 2)
					- (2 * adLength * dcLength * Math.cos(Math
							.toRadians(cdaAngle))));
			found = true;
		}
	}

	private void calculateTrapeziumDiagonal2() {
		if (baLength != 0 && height != 0 && help1 != 0) {
			diagonal2 = Math.sqrt(Math.pow(baLength - help1, 2)
					+ Math.pow(height, 2));
			found = true;
		} else if (baLength != 0 && adLength != 0 && dabAngle != 0) {
			diagonal2 = Math.sqrt(Math.pow(baLength, 2)
					+ Math.pow(adLength, 2)
					- (2 * baLength * adLength * Math.cos(Math
							.toRadians(dabAngle))));
			found = true;
		} else if (cbLength != 0 && dcLength != 0 && bcdAngle != 0) {
			diagonal2 = Math.sqrt(Math.pow(cbLength, 2)
					+ Math.pow(dcLength, 2)
					- (2 * cbLength * dcLength * Math.cos(Math
							.toRadians(bcdAngle))));
			found = true;
		}
	}

	private void calculateTrapeziumHeight() {
		if (cbLength != 0 && abcAngle != 0) {
			height = roundToDecimals(
					cbLength * Math.sin(Math.toRadians(abcAngle)), 2);
			found = true;
		} else if (cbLength != 0 && help2 != 0) {
			height = roundToDecimals(
					Math.sqrt(Math.pow(cbLength, 2) - Math.pow(help2, 2)), 2);
			found = true;
		} else if (adLength != 0 && dabAngle != 0) {
			height = roundToDecimals(
					adLength * Math.sin(Math.toRadians(dabAngle)), 2);
			found = true;
		} else if (adLength != 0 && help1 != 0) {
			height = roundToDecimals(
					Math.sqrt(Math.pow(adLength, 2) - Math.pow(help1, 2)), 2);
			found = true;
		} else if (area != 0 && baLength != 0 && dcLength != 0) {
			height = roundToDecimals((2 * area) / (baLength + dcLength), 2);
			found = true;
		} else if (baLength != 0) {
			if (diagonal1 != 0 && help2 != 0) {
				height = roundToDecimals(
						Math.sqrt(Math.pow(diagonal1, 2)
								- Math.pow(baLength - help2, 2)), 2);
				found = true;
			} else if (diagonal2 != 0 && help1 != 0) {
				height = roundToDecimals(
						Math.sqrt(Math.pow(diagonal2, 2)
								- Math.pow(baLength - help1, 2)), 2);
				found = true;
			}
		}

	}

	private void calculateRhomboid() {
		do {
			found = false;
			before = false;
			calculated = false;

			before = adLength != 0;
			calculateRhomboidSide1();
			if (!before && found) {
				calculated = true;
			}

			before = dcLength != 0;
			calculateRhomboidSide2();
			if (!before && found) {
				calculated = true;
			}

			before = abcAngle != 0;
			calculateRhomboidAbcAngle();
			if (!before && found) {
				calculated = true;
			}

			before = dabAngle != 0;
			calculateRhomboidDabAngle();
			if (!before && found) {
				calculated = true;
			}

			before = height != 0;
			calculateRhomboidHeight();
			if (!before && found) {
				calculated = true;
			}

			before = area != 0;
			calculateRhomboidArea();
			if (!before && found) {
				calculated = true;
			}

			before = circumference != 0;
			calculateRhomboidCircumference();
			if (!before && found) {
				calculated = true;
			}

			before = diagonal1 != 0;
			calculateRhomboidDiagonal1();
			if (!before && found) {
				calculated = true;
			}

			before = diagonal2 != 0;
			calculateRhomboidDiagonal2();
			if (!before && found) {
				calculated = true;
			}

		} while (calculated);
	}

	private void calculateRhomboidSide1() {
		if (dcLength != 0) {
			if (circumference != 0) {
				adLength = (circumference - (2 * dcLength)) / 2;
				found = true;
			} else if (area != 0 && dabAngle != 0) {
				adLength = area
						/ (dcLength * Math.sin(Math.toRadians(dabAngle)));
				found = true;
			}
		} else if (height != 0 && dabAngle != 0) {
			adLength = height / Math.sin(Math.toRadians(dabAngle));
			found = true;
		}
	}

	private void calculateRhomboidSide2() {
		if (circumference != 0 && adLength != 0) {
			dcLength = (circumference - (2 * adLength)) / 2;
			found = true;
		} else if (area != 0 && height != 0) {
			dcLength = area / height;
			found = true;
		}
	}

	private void calculateRhomboidAbcAngle() {
		if (dabAngle != 0) {
			abcAngle = 180 - dabAngle;
			found = true;
		} else if (adLength != 0 && dcLength != 0 && diagonal1 != 0) {
			abcAngle = Math.toDegrees(Math.acos((Math.pow(dcLength, 2)
					+ Math.pow(adLength, 2) - Math.pow(diagonal1, 2))
					/ (2 * dcLength * adLength)));
			found = true;
		}
	}

	private void calculateRhomboidDabAngle() {
		if (abcAngle != 0) {
			dabAngle = 180 - abcAngle;
			found = true;
		} else if (adLength != 0 && dcLength != 0 && diagonal2 != 0) {
			dabAngle = Math.toDegrees(Math.acos((Math.pow(dcLength, 2)
					+ Math.pow(adLength, 2) - Math.pow(diagonal2, 2))
					/ (2 * dcLength * adLength)));
			found = true;
		} else if (height != 0 && adLength != 0) {
			dabAngle = Math.toDegrees(Math.asin(height / adLength));
			found = true;
		} else if (area != 0 && adLength != 0 && dcLength != 0) {
			dabAngle = Math.toDegrees(Math.asin(area / (dcLength * adLength)));
			found = true;
		}

	}

	private void calculateRhomboidHeight() {
		if (adLength != 0 && dabAngle != 0) {
			height = adLength * Math.sin(Math.toRadians(dabAngle));
			found = true;
		}
	}

	private void calculateRhomboidArea() {
		if (height != 0 && dcLength != 0) {
			area = dcLength * height;
			found = true;
		}
	}

	private void calculateRhomboidCircumference() {
		if (adLength != 0 && dcLength != 0) {
			circumference = (2 * adLength) + (2 * dcLength);
			found = true;
		}

	}

	private void calculateRhomboidDiagonal1() {
		if (adLength != 0 && dcLength != 0 && abcAngle != 0) {
			diagonal1 = Math.sqrt(Math.pow(adLength, 2)
					+ Math.pow(dcLength, 2)
					- (2 * dcLength * adLength * Math.cos(Math
							.toRadians(abcAngle))));
			found = true;
		}
	}

	private void calculateRhomboidDiagonal2() {
		if (adLength != 0 && dcLength != 0 && dabAngle != 0) {
			diagonal2 = Math.sqrt(Math.pow(adLength, 2)
					+ Math.pow(dcLength, 2)
					- (2 * dcLength * adLength * Math.cos(Math
							.toRadians(dabAngle))));
			found = true;
		}
	}

	private void setRhomboidDefaults() {
		cbLength = adLength;
		baLength = dcLength;
		bcdAngle = dabAngle;
		cdaAngle = abcAngle;
	}

	private void calculateRhombus() {
		do {
			found = false;
			before = false;
			calculated = false;

			before = adLength != 0;
			calculateRhombusSide();
			if (!before && found) {
				calculated = true;
			}

			before = dabAngle != 0;
			calculateRhombusDabAngle();
			if (!before && found) {
				calculated = true;
			}

			before = abcAngle != 0;
			calculateRhombusAbcAngle();
			if (!before && found) {
				calculated = true;
			}

			before = height != 0;
			calculateRhombusHeight();
			if (!before && found) {
				calculated = true;
			}

			before = area != 0;
			calculateRhombusArea();
			if (!before && found) {
				calculated = true;
			}

			before = circumference != 0;
			calculateRhombusCircumference();
			if (!before && found) {
				calculated = true;
			}

			before = diagonal2 != 0;
			calculateRhombusDiagonal1();
			if (!before && found) {
				calculated = true;
			}

			before = diagonal2 != 0;
			calculateRhombusDiagonal2();
			if (!before && found) {
				calculated = true;
			}
		} while (calculated);
	}

	private void calculateRhombusSide() {
		double angle = 0;
		if (abcAngle != 0) {
			angle = Math.toRadians(abcAngle);
		} else if (bcdAngle != 0) {
			angle = Math.toRadians(bcdAngle);
		}
		if (area != 0) {
			if (height != 0) {
				adLength = area / height;
				found = true;
			} else if (angle != 0) {
				adLength = Math.sqrt(area / Math.sin(angle));
				found = true;
			}
		} else if (diagonal1 != 0 && diagonal2 != 0) {
			adLength = Math.sqrt(Math.pow(diagonal1 / 2, 2)
					+ Math.pow(diagonal2, 2));
			found = true;
		} else if (circumference != 0) {
			adLength = circumference / 4;
			found = true;
		} else if (diagonal1 != 0 && abcAngle != 0) {

		}

	}

	private void calculateRhombusDiagonal1() {
		if (diagonal2 != 0) {
			if (adLength != 0) {
				diagonal1 = 2 * Math.sqrt(Math.pow(adLength, 2)
						- Math.pow(diagonal2 / 2, 2));
				found = true;
			} else if (area != 0) {
				diagonal1 = (2 * area) / diagonal2;
				found = true;
			} else if (circumference != 0) {
				diagonal1 = 2 * Math.sqrt(Math.pow(circumference / 4, 2)
						- Math.pow(diagonal2 / 2, 2));
				found = true;
			}
		} else if (adLength != 0 && abcAngle != 0) {
			diagonal1 = Math.abs(Math.sqrt((2 * Math.pow(adLength, 2))
					- (2 * Math.pow(adLength, 2) * Math.cos(Math
							.toRadians(abcAngle)))));
			found = true;
		}
	}

	private void calculateRhombusDiagonal2() {
		if (diagonal1 != 0) {
			if (adLength != 0) {
				diagonal2 = 2 * Math.sqrt(Math.pow(adLength, 2)
						- Math.pow(diagonal1 / 2, 2));
				found = true;
			} else if (area != 0) {
				diagonal2 = (2 * area) / diagonal1;
				found = true;
			} else if (circumference != 0) {
				diagonal2 = 2 * Math.sqrt(Math.pow(circumference / 4, 2)
						- Math.pow(diagonal1, 2));
				found = true;
			}
		} else if (adLength != 0 && bcdAngle != 0) {
			diagonal2 = Math.abs(Math.sqrt((2 * Math.pow(adLength, 2))
					- (2 * Math.pow(adLength, 2) * Math.cos(Math
							.toRadians(bcdAngle)))));
			found = true;
		}
	}

	private void calculateRhombusHeight() {
		double angle = 0;
		if (abcAngle != 0) {
			angle = Math.toRadians(abcAngle);
		} else if (bcdAngle != 0) {
			angle = Math.toRadians(bcdAngle);
		}
		if (adLength != 0) {
			if (area != 0) {
				height = area / adLength;
				found = true;
			} else if (angle != 0) {
				height = adLength * Math.sin(angle);
				found = true;
			} else if (diagonal1 != 0 && diagonal2 != 0) {
				height = (diagonal1 * diagonal2) / (2 * adLength);
				found = true;
			} else if (diagonal1 != 0) {
				height = (diagonal1 * 2 * Math.sqrt(Math.pow(adLength, 2)
						- Math.pow(diagonal1 / 2, 2)))
						/ (2 * adLength);
				found = true;
			} else if (diagonal2 != 0) {
				height = (diagonal2 * 2 * Math.sqrt(Math.pow(adLength, 2)
						- Math.pow(diagonal2 / 2, 2)))
						/ (2 * adLength);
				found = true;
			}
		} else if (circumference != 0) {
			if (area != 0) {
				height = (4 * area) / circumference;
				found = true;
			} else if (diagonal1 != 0 && diagonal2 != 0) {
				height = (2 * diagonal1 * diagonal2) / circumference;
				found = true;
			} else if (diagonal1 != 0) {
				height = (2 * diagonal1 * 2 * Math.sqrt(Math.pow(adLength, 2)
						- Math.pow(diagonal1 / 2, 2)))
						/ circumference;
				found = true;
			} else if (diagonal2 != 0) {
				height = (2 * diagonal2 * 2 * Math.sqrt(Math.pow(adLength, 2)
						- Math.pow(diagonal2 / 2, 2)))
						/ circumference;
				found = true;
			}
		}

	}

	private void calculateRhombusArea() {
		double angle = 0;
		if (abcAngle != 0) {
			angle = Math.toRadians(abcAngle);
		} else if (bcdAngle != 0) {
			angle = Math.toRadians(bcdAngle);
		}
		if (adLength != 0) {
			if (height != 0) {
				area = height * adLength;
				found = true;
			} else if (angle != 0) {
				area = Math.pow(adLength, 2) * Math.sin(angle);
				found = true;
			} else if (diagonal1 != 0) {
				area = (diagonal1 * 2 * Math.sqrt(Math.pow(adLength, 2)
						- Math.pow(diagonal1 / 2, 2))) / 2;
				found = true;
			} else if (diagonal2 != 0) {
				area = (diagonal2 * 2 * Math.sqrt(Math.pow(adLength, 2)
						- Math.pow(diagonal2 / 2, 2))) / 2;
				found = true;
			}
		} else if (diagonal1 != 0 && diagonal2 != 0) {
			area = (diagonal1 * diagonal2) / 2;
			found = true;
		} else if (height != 0 && circumference != 0) {
			area = (height * circumference) / 4;
			found = true;
		}
	}

	private void calculateRhombusCircumference() {
		double angle = 0;
		if (abcAngle != 0) {
			angle = Math.toRadians(abcAngle);
		} else if (bcdAngle != 0) {
			angle = Math.toRadians(bcdAngle);
		}
		if (adLength != 0) {
			circumference = 4 * adLength;
			found = true;
		} else if (area != 0) {
			if (height != 0) {
				circumference = (4 * area) / height;
				found = true;
			} else if (angle != 0) {
				circumference = 4 * Math.sqrt(area / Math.sin(angle));
				found = true;
			}
		} else if (diagonal1 != 0 && diagonal2 != 0) {
			circumference = 4 * Math.sqrt(Math.pow(diagonal1 / 2, 2)
					+ Math.pow(diagonal2, 2));
			found = true;
		}
	}

	private void calculateRhombusAbcAngle() {
		if (dabAngle != 0) {
			abcAngle = 180 - dabAngle;
			found = true;
		} else if (diagonal1 != 0) {
			if (adLength != 0) {
				abcAngle = Math.toDegrees(Math.acos(roundToDecimals(1 - (Math
						.pow(diagonal1, 2) / (2 * Math.pow(adLength, 2))), 2)));
				found = true;
			} else if (circumference != 0) {
				abcAngle = Math.toDegrees(Math.acos(1 - ((Math
						.pow(diagonal1, 2) * 16) / (2 * Math.pow(circumference,
						2)))));
				found = true;
			} else if (area != 0) {
				abcAngle = Math.toDegrees(Math.acos(1 - ((Math
						.pow(diagonal1, 2) * Math.pow(height, 2)) / (2 * Math
						.pow(area, 2)))));
				found = true;
			}
		} else if (adLength != 0 && height != 0) {
			abcAngle = 180 - Math.toDegrees(Math.asin(height / adLength));
		}
	}

	private void calculateRhombusDabAngle() {
		if (abcAngle != 0) {
			dabAngle = 180 - abcAngle;
			found = true;
		} else if (diagonal2 != 0) {
			if (adLength != 0) {
				dabAngle = Math.toDegrees(Math.acos(roundToDecimals(
						((2 * Math.pow(adLength, 2)) - Math.pow(diagonal2, 2))
								/ (2 * Math.pow(adLength, 2)), 2)));
				found = true;
			} else if (circumference != 0) {
				dabAngle = Math.toDegrees(Math.acos(1 - ((Math
						.pow(diagonal2, 2) * 16) / (2 * Math.pow(circumference,
						2)))));
				found = true;
			} else if (area != 0) {
				dabAngle = Math.toDegrees(Math.acos(1 - ((Math
						.pow(diagonal2, 2) * Math.pow(height, 2)) / (2 * Math
						.pow(area, 2)))));
				found = true;
			}
		} else if (adLength != 0 && height != 0) {
			dabAngle = Math.toDegrees(Math.asin(height / adLength));
		}
	}

	private void setRhombusDefaults() {
		dcLength = cbLength = baLength = adLength;
		bcdAngle = dabAngle;
		cdaAngle = abcAngle;
	}

	private void calculateOblong() {
		do {
			found = false;
			before = false;
			calculated = false;

			before = adLength != 0;
			calculateOblongSide1();
			if (!before && found) {
				calculated = true;
			}

			before = dcLength != 0;
			calculateOblongSide2();
			if (!before && found) {
				calculated = true;
			}

			before = diagonal1 != 0;
			calculateOblongDiagonal();
			if (!before && found) {
				calculated = true;
			}

			before = area != 0;
			calculateOblongArea();
			if (!before && found) {
				calculated = true;
			}

			before = circumference != 0;
			calculateOblongCircumference();
			if (!before && found) {
				calculated = true;
			}
		} while (calculated);

	}

	private void calculateOblongSide1() {
		if (dcLength != 0) {
			if (area != 0) {
				adLength = area / dcLength;
				found = true;
			} else if (circumference != 0) {
				adLength = (circumference - (2 * dcLength)) / 2;
				found = true;
			} else if (diagonal1 != 0) {
				adLength = Math.sqrt(Math.pow(diagonal1, 2)
						- Math.pow(dcLength, 2));
				found = true;
			}
		}

	}

	private void calculateOblongSide2() {
		if (adLength != 0) {
			if (area != 0) {
				dcLength = area / adLength;
				found = true;
			} else if (circumference != 0) {
				dcLength = (circumference - (2 * adLength)) / 2;
				found = true;
			} else if (diagonal1 != 0) {
				dcLength = Math.sqrt(Math.pow(diagonal1, 2)
						- Math.pow(adLength, 2));
				found = true;
			}
		}
	}

	private void calculateOblongDiagonal() {
		double side = 0;
		if (adLength != 0 && dcLength != 0) {
			diagonal1 = Math
					.sqrt(Math.pow(adLength, 2) + Math.pow(dcLength, 2));
			found = true;
		} else if (adLength != 0) {
			side = adLength;
		} else if (dcLength != 0) {
			side = dcLength;
		}
		if (side != 0) {
			if (area != 0) {
				diagonal1 = Math.sqrt(Math.pow(side, 2)
						+ Math.pow((area / side), 2));
				found = true;
			} else if (circumference != 0) {
				diagonal1 = Math.sqrt(Math.pow(side, 2)
						+ Math.pow(((circumference - (2 * side)) / 2), 2));
				found = true;
			}
		}

	}

	private void calculateOblongArea() {
		double side = 0;
		if (adLength != 0 && dcLength != 0) {
			area = adLength * dcLength;
			found = true;
		} else if (adLength != 0) {
			side = adLength;
		} else if (dcLength != 0) {
			side = dcLength;
		}
		if (side != 0) {
			if (circumference != 0) {
				area = (side * (circumference - (2 * side))) / 2;
				found = true;
			} else if (diagonal1 != 0) {
				area = side
						* Math.sqrt(Math.pow(diagonal1, 2) - Math.pow(side, 2));
				found = true;
			}
		}
	}

	private void calculateOblongCircumference() {
		double side = 0;
		if (adLength != 0 && dcLength != 0) {
			circumference = 2 * (adLength + dcLength);
			found = true;
		} else if (adLength != 0) {
			side = adLength;
		} else if (dcLength != 0) {
			side = dcLength;
		}
		if (side != 0) {
			if (area != 0) {
				circumference = 2 * ((area / side) + side);
				found = true;
			} else if (diagonal1 != 0) {
				circumference = 2 * (Math.sqrt(Math.pow(diagonal1, 2)
						- Math.pow(side, 2)) + side);
				found = true;
			}
		}

	}

	private void setOblongDefaults() {
		height = cbLength = adLength;
		baLength = dcLength;
		diagonal2 = diagonal1;
		dabAngle = abcAngle = bcdAngle = cdaAngle = 90;
	}

	private void calculateSquare() {
		do {
			found = false;
			calculated = false;

			before = adLength != 0;
			calculateSquareSide();
			if (!before && found) {
				calculated = true;
			}

			before = diagonal1 != 0;
			calculateSquareDiagonal();
			if (!before && found) {
				calculated = true;
			}

			before = area != 0;
			calculateSquareArea();
			if (!before && found) {
				calculated = true;
			}

			before = circumference != 0;
			calculateSquareCircumference();
			if (!before && found) {
				calculated = true;
			}
		} while (calculated);
	}

	private void calculateSquareSide() {
		if (circumference != 0) {
			adLength = circumference / 4;
			found = true;
		} else if (area != 0) {
			adLength = Math.sqrt(area);
			found = true;
		} else if (diagonal1 != 0) {
			adLength = diagonal1 / Math.sqrt(2);
			found = true;
		}
	}

	private void calculateSquareDiagonal() {
		if (circumference != 0) {
			diagonal1 = (Math.sqrt(2) * circumference) / 4;
			found = true;
		} else if (area != 0) {
			diagonal1 = Math.sqrt(2 * area);
			found = true;
		} else if (adLength != 0) {
			diagonal1 = Math.sqrt(2) * adLength;
			found = true;
		}

	}

	private void calculateSquareArea() {
		if (circumference != 0) {
			area = Math.pow(circumference, 2) / 16;
			found = true;
		} else if (diagonal1 != 0) {
			area = Math.pow(diagonal1, 2) / 2;
			found = true;
		} else if (adLength != 0) {
			area = Math.pow(adLength, 2);
			found = true;
		}
	}

	private void calculateSquareCircumference() {
		if (diagonal1 != 0) {
			circumference = (4 * diagonal1) / Math.sqrt(2);
			found = true;
		} else if (area != 0) {
			circumference = 4 * Math.sqrt(area);
			found = true;
		} else if (adLength != 0) {
			circumference = 4 * adLength;
			found = true;
		}
	}

	private void setSquareDefaults() {
		height = dcLength = cbLength = baLength = adLength;
		diagonal2 = diagonal1;
		dabAngle = 90.0;
		abcAngle = 90.0;
		bcdAngle = 90.0;
		cdaAngle = 90.0;
	}
}
